package top.huxy.boot.service.impl.qqBot.groupTrigger;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.huxy.boot.model.entity.Chenyu;
import top.huxy.boot.service.ChenyuService;
import top.huxy.qqbot.core.roundrobin.AbstractGroupMessageTrigger;

import java.time.Duration;
import java.util.*;

/**
 * @author HuXY
 */
@Component
public class ChenYuJieLong extends AbstractGroupMessageTrigger {

    private Chenyu currentChenyu;
    private static final HanyuPinyinOutputFormat FORMAT = new HanyuPinyinOutputFormat();
    private final Set<String> historyChenyu = Collections.synchronizedSet(new HashSet<>());
    private long lastTime;

    @Autowired
    public ChenyuService chenyuService;

    static {
        FORMAT.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        FORMAT.setVCharType(HanyuPinyinVCharType.WITH_V);
    }

    @Override
    protected void handlerGroupMessage() {
        if (currentChenyu == null) {
            initChenYu();
        }

        if ("成语接龙".equals(getRawMessage())) {
            showCurrentChenYu();
        } else if ("成语接龙 提示".equals(getRawMessage())) {
            showChenYuJieLongTip();
        } else if ("成语接龙 重置".equals(getRawMessage())) {
            resetChenYuJieLong();
        } else if (getRawMessage().length() == 4) {
            tryChenYuJieLong();
        }
    }

    private void tryChenYuJieLong() {
        //rawMessage的第一个字正好与currentChenyu的最后一个字拼音吻合，尝试接龙
        String[] p1 = pinyin2pinyinArray(currentChenyu.getEnd());
        String[] p2 = getPinYinEnd(getRawMessage().charAt(0));
        if (match(p1, p2)) {
            if (historyChenyu.contains(getRawMessage())) {
                at();
                text("\n接龙失败");
                text("\n<" + getRawMessage() + ">已经使用过了喔").send();
            } else {
                Chenyu newChenyu = findChenyu(getRawMessage());
                if (newChenyu != null) {
                    String[] newPinYinEnd = getPinYinEnd(getRawMessage().charAt(3));
                    at();
                    text("\n接龙成功");
                    text("\n下个成语<" + getRawMessage() + ">\n");
                    text(Arrays.toString(newPinYinEnd)).send();
                    setCurrentChenYu(newChenyu);
                } else {
                    at();
                    text("\n接龙失败\n<");
                    text(getRawMessage() + ">不是成语哟~").send();
                }
            }
        }
    }

    private void resetChenYuJieLong() {
        int minutes = 5;
        if (System.currentTimeMillis() - lastTime < Duration.ofMinutes(minutes).toMillis()) {
            at();
            text("\n目前无法重置").send();
        } else {
            historyChenyu.clear();
            initChenYu();
            text("成语接龙\n已重置").send();
            showCurrentChenYu();
        }
    }

    private void setCurrentChenYu(Chenyu newChenyu) {
        this.currentChenyu = newChenyu;
        this.historyChenyu.add(newChenyu.getText());
        lastTime = System.currentTimeMillis();
    }

    private Chenyu findChenyu(String text) {
        return chenyuService.findChenYu(text);
    }

    private boolean match(String[] p1, String[] p2) {
        for (String s1 : p1) {
            for (String s2 : p2) {
                if (s1 != null && Objects.equals(s1, s2)) {
                    return true;
                }
            }
        }
        return false;
    }

    private String[] getPinYinEnd(char c) {
        try {
            return PinyinHelper.toHanyuPinyinStringArray(c, FORMAT);
        } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
            badHanyuPinyinOutputFormatCombination.printStackTrace();
            return new String[]{};
        }
    }

    private String pinyinArray2pinyin(String[] pinyin) {
        if (pinyin == null) {
            return "";
        }
        StringJoiner sj = new StringJoiner(";");
        for (String s : pinyin) {
            sj.add(s);
        }
        return sj.toString();
    }

    private String[] pinyin2pinyinArray(String pinyin) {
        if (pinyin == null) {
            return new String[]{};
        }
        return new HashSet<>(Arrays.asList(pinyin.split(";"))).toArray(new String[0]);
    }

    private void showChenYuJieLongTip() {

    }

    private void showCurrentChenYu() {
        at();
        text("\n当前成语<" + currentChenyu.getText() + ">\n");
        text(Arrays.toString(pinyin2pinyinArray(currentChenyu.getEnd()))).send();
    }

    private void initChenYu() {
        Chenyu randomChenyu = chenyuService.getRandomChenyu();
        if (randomChenyu == null) {
            System.out.println("randomChenyu must be not null");
        } else {
            setCurrentChenYu(randomChenyu);
        }
    }
}
